package com.squeekeek.util.qrcode.Ui;

import android.hardware.Camera;
import android.view.SurfaceHolder;

public class CameraSurfaceHolder implements SurfaceHolder.Callback {
	private SurfaceHolder myCameraViewHolder = null;
	private Camera myCamera = null;
	
	public CameraSurfaceHolder(Camera c, SurfaceHolder cameraViewHolder) {
		this.myCameraViewHolder = cameraViewHolder;
		this.myCameraViewHolder.addCallback(this);
		
		// Some devices do not do this automatically
		// although this is deprecated
		this.myCameraViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		
		this.myCamera = c;
	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		Camera.Parameters cameraParams;
		Camera.Size cameraSize;
		
		try {
			// Set orientation
			cameraParams = this.myCamera.getParameters();
			cameraSize = getBestPreviewSize(cameraParams, width, height);
			
			// Stop preview
			this.myCamera.stopPreview();
			
			// Really, this rotation correction is very unnerving!
			this.myCamera.setPreviewDisplay(holder);
			this.myCamera.setDisplayOrientation(90);
			
			if(cameraSize != null) {
				// Set the best size
				cameraParams.setPreviewSize(cameraSize.width, cameraSize.height);
			}
			else {
				// Set the default size
				cameraParams.setPreviewSize(width, height);
			}
			
			// Restart it
			this.myCamera.startPreview();
		}
		catch(Exception e) {
			// Do nothing for now
		}
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		try {
			this.myCamera.setPreviewDisplay(holder);
		}
		catch(Exception e) {
		}
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		try {
			// Just stop the preview. Release it at the main activity.
			this.myCamera.stopPreview();
		}
		catch(Exception e) {
			// Usually results after activity pauses. Do nothing.
		}
	}
	
	private Camera.Size getBestPreviewSize(Camera.Parameters p, int w, int h) {
		int bestDelta;
		int nowDelta;
		Camera.Size outSize = null;	
		
		for(Camera.Size iSize : p.getSupportedPictureSizes()) {
			
			// Set size
			if(iSize.width <= w && iSize.height <= h) {
				if(outSize == null) {
					outSize = iSize;
				}
				else {
					// Maximize size such that it fits the given width and
					// height
					nowDelta = w - iSize.width + h - iSize.height;
					bestDelta = w - outSize.width + h - outSize.height;
					
					if(nowDelta < bestDelta) {
						outSize = iSize;
					}
				}
			}
		}
		
		return outSize;
	}

}
